#include once <neg32.asm>

__FTOU32REG:	; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed)
; Input FP number in A EDCB (A exponent, EDCB mantissa)
; Output: DEHL 32 bit number (signed)
                     ;- PROC
                     ;- LOCAL __IS_FLOAT
ora z80_a            ;- or a
jne __IS_FLOAT       ;- jr nz, __IS_FLOAT
; Here if it is a ZX ROM Integer
lda z80_c            ;- ld h,c
sta z80_h
lda z80_d            ;- ld l,d
sta z80_l
lda z80_e            ;- ld a,e	 ; Takes sign: FF = -, 0 = +
sta z80_a
lda #<0              ;- ld de,0
sta z80_e
lda #>0
sta z80_d
clc                  ;- inc a
adc #$01
jeq __NEG32          ;- jp z, __NEG32	; Negates if negative
rts                  ;- ret

__IS_FLOAT:  ; Jumps here if it is a true floating point number
lda z80_e            ;- ld h,e
sta z80_h
lda z80_l            ;- push hl  ; Stores it for later (Contains Sign in H)
pha
lda z80_h
pha
lda z80_e            ;- push de
pha
lda z80_d
pha
lda z80_c            ;- push bc
pha
lda z80_b
pha
lda z80_c            ;- exx
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
pla                  ;- pop de   ; Loads mantissa into C'B' E'D'
sta z80_d
pla
sta z80_e
pla                  ;- pop bc	 ;
sta z80_b
pla
sta z80_c
lda z80_c            ;- set 7,c ; Highest mantissa bit is always 1
ora #$80
sta z80_c
lda z80_c            ;- exx
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
                     ;- ld hl,0 ; DEHL = 0
lda z80_h            ;- ld d,h
sta z80_d
lda z80_l            ;- ld e,l
sta z80_e
;ld a, c  ; Get exponent
                     ;- sub 128  ; Exponent -= 128
jeq __FTOU32REG_END  ;- jr z, __FTOU32REG_END	; If it was <= 128, we are done (Integers must be > 128)
jcc __FTOU32REG_END  ;- jr c, __FTOU32REG_END	; It was decimal (0.xxx). We are done (return 0)
lda z80_a            ;- ld b, a  ; Loop counter = exponent - 128
sta z80_b

__FTOU32REG_LOOP:
lda z80_c            ;- exx 	 ; Shift C'B' E'D' << 1, output bit stays in Carry
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
asl z80_d            ;- sla d
rol z80_e            ;- rl e
rol z80_b            ;- rl b
rol z80_c            ;- rl c
lda z80_c            ;- exx		 ; Shift DEHL << 1, inserting the carry on the right
ldx z80_cp
stx z80_c
sta z80_cp
lda z80_b
ldx z80_bp
stx z80_b
sta z80_bp
lda z80_e
ldx z80_ep
stx z80_e
sta z80_ep
lda z80_d
ldx z80_dp
stx z80_d
sta z80_dp
lda z80_l
ldx z80_lp
stx z80_l
sta z80_lp
lda z80_h
ldx z80_hp
stx z80_h
sta z80_hp
rol z80_l            ;- rl l
rol z80_h            ;- rl h
rol z80_e            ;- rl e
rol z80_d            ;- rl d
                     ;- djnz __FTOU32REG_LOOP

__FTOU32REG_END:
plp                  ;- pop af   ; Take the sign bit
pha
ora z80_a            ;- or a	 ; Sets SGN bit to 1 if negative
                     ;- jp m, __NEG32 ; Negates DEHL
rts                  ;- ret
                     ;- ENDP

__FTOU8:	; Converts float in C ED LH to Unsigned byte in A
jsr __FTOU32REG      ;- call __FTOU32REG
lda z80_l            ;- ld a,l
sta z80_a
rts                  ;- ret

